-------------------------------------------------------------------------------
-- Archivo: 			         control_unit.vhdl
-- Fecha de creación:            25/01/2011
-- Ultima fecha de modificacion: 28/01/2011
-- Diseñador: 			         Cesar A. Fuguet T.
-- Diseño: 			             control_unit
-- Propósito: 			         Unidad de control para el microprocesador 
-- 				                 vectorial
-------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;

entity control_unit is
    port (
        VA_i          : in  std_logic_vector(1 downto 0);
        VB_i          : in  std_logic_vector(1 downto 0);
        VD_i          : in  std_logic_vector(1 downto 0);
        CONST2_i      : in  std_logic_vector(1 downto 0);
        OPCODE_i      : in  std_logic_vector(3 downto 0);
        HAZARD_i      : in  std_logic;
        CLK_i         : in  std_logic;
        RESET_i       : in  std_logic;
        IDXI_o        : out std_logic_vector(3 downto 0);
        IDXJ_o        : out std_logic_vector(3 downto 0);
        IDXK_o        : out std_logic_vector(3 downto 0);
        ALU_OP_o      : out std_logic_vector(3 downto 0);
        CONST6_o      : out std_logic_vector(5 downto 0);
        CONST_MUX_o   : out std_logic;
        INSTR_FETCH_o : out std_logic;
        WE_o          : out std_logic);

end control_unit;

architecture structural of control_unit is

    component fft_fsm
        port(
            COUNTER_i   : in  std_logic_vector(1 downto 0);
            OPCODE_i    : in  std_logic_vector(3 downto 0);
            CLK_i       : in  std_logic;
            RESET_i     : in  std_logic;
            FFT_STG_o   : out std_logic_vector(2 downto 0));
    end component;

    component hazard_fsm
        port (
            COUNTER_i    : in  std_logic_vector(1 downto 0);
            HAZARD_i     : in  std_logic;
            CLK_i        : in  std_logic;
            RESET_i      : in  std_logic;
            OPCODE_i     : in  std_logic_vector(3 downto 0);
            FFT_STG_i    : in  std_logic_vector(2 downto 0);
            HAZARD_FSM_o : out std_logic;
            HAZARD_NXT_o : out std_logic);
    end component;

    component index_unit
        port (
            OPCODE_i       : in  std_logic_vector(3 downto 0);
            COUNTER_i      : in  std_logic_vector(1 downto 0);
            VA_i           : in  std_logic_vector(1 downto 0);
            VB_i           : in  std_logic_vector(1 downto 0);
            VD_i           : in  std_logic_vector(1 downto 0);
            CONST2_i       : in  std_logic_vector(1 downto 0);
            HAZARD_FSM_i   : in  std_logic;
            HAZARD_NXT_i   : in  std_logic;
            FFT_STG_i      : in  std_logic_vector(2 downto 0);
            IDXI_o         : out std_logic_vector(3 downto 0);
            IDXJ_o         : out std_logic_vector(3 downto 0);
            IDXK_o         : out std_logic_vector(3 downto 0);
            CONST6_o       : out std_logic_vector(5 downto 0);
            CONST_MUX_o    : out std_logic;
            INSTR_FETCH_o  : out std_logic;
            WE_o           : out std_logic);
    end component;

    component op_unit
        port (
            OPCODE_i  : in  std_logic_vector(3 downto 0);
            FFT_STG_i : in  std_logic_vector(2 downto 0);
            COUNTER_i : in  std_logic_vector(1 downto 0);
            ALU_OP_o  : out std_logic_vector(3 downto 0));
    end component;

    component counter
        port (
            CLK_i     : in std_logic;
            RESET_i   : in std_logic;
            COUNTER_o : out std_logic_vector(1 downto 0));
    end component;

    signal counter_wire : std_logic_vector(1 downto 0);
    signal fft_stg_wire : std_logic_vector(2 downto 0);
    signal hazard_fsm_wire : std_logic;
    signal hazard_nxt_wire : std_logic;

begin

    FFT_FSM0 : fft_fsm port map (
        COUNTER_i   => counter_wire,
        OPCODE_i    => OPCODE_i,
        CLK_i       => CLK_i,
        RESET_i     => RESET_i,
        FFT_STG_o   => fft_stg_wire);

    HAZARD_FSM0 : hazard_fsm port map (
        COUNTER_i    => counter_wire, 
        HAZARD_i     => HAZARD_i,
        CLK_i        => CLK_i,
        RESET_i      => RESET_i,
        OPCODE_i     => OPCODE_i,
        FFT_STG_i    => fft_stg_wire,
        HAZARD_FSM_o => hazard_fsm_wire,
        HAZARD_NXT_o => hazard_nxt_wire);

    INDEX_UNIT0 : index_unit port map (
        OPCODE_i      => OPCODE_i,
        COUNTER_i     => counter_wire,
        VA_i          => VA_i,
        VB_i          => VB_i,
        VD_i          => VD_i,
        CONST2_i      => CONST2_i,
        HAZARD_FSM_i  => hazard_fsm_wire,
        HAZARD_NXT_i  => hazard_nxt_wire,
        FFT_STG_i     => fft_stg_wire,
        IDXI_o        => IDXI_o,
        IDXJ_o        => IDXJ_o,
        IDXK_o        => IDXK_o,
        CONST_MUX_o   => CONST_MUX_o,
        CONST6_o      => CONST6_o,
        INSTR_FETCH_o => INSTR_FETCH_o, 
        WE_o          => WE_o);

    COUNTER0 : counter port map (
            CLK_i     => CLK_i, 
            RESET_i   => RESET_i,
            COUNTER_o => counter_wire);

    OP_UNIT0 : op_unit port map (
        OPCODE_i  => OPCODE_i,
        FFT_STG_i => fft_stg_wire,
        COUNTER_i => counter_wire,
        ALU_OP_o  => ALU_OP_o);

end structural;

-- vim: tabstop=4 : expandtab : shiftwidth=4
